using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Collections;
using System.Text;
using Thinxoft.HttpLib;
using System.Reflection;
using System.Windows.Forms;
using SHDocVw;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using System.Runtime.Remoting;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.Net.NetworkInformation;
using System.Collections.Generic;
using System.Runtime.Remoting.Lifetime;


namespace Thinxoft.XedusLive
{
	/// <summary>
	/// Summary description for Class1.
	/// </summary>
	partial class Start
	{
        static Settings xsettings;
        static ServerState xstate;
        static string email;
		static WebAdmin webAdmin;
		static bool connected;
		static SiteBuilderForm sbf;
		static InfoForm info ;

		static StartForm sf;
		static ShellWindowsClass shells = new ShellWindowsClass();
        static Process   p2;

        static bool running;
        
        
        //static Identity.IdentityService idService = new Thinxoft.XedusLive.Identity.IdentityService();

		#region [properties]

        public static bool ServerRunning
        {
            get
            {
                return running;
            }
        }

        internal static ServerState XedusState
        {
			get
			{
				return xstate;
			}
		}

		public static string Email
		{
			get{return email;}
			set{email = value;}
		}

		public static WebAdmin AdminUI
		{
			get
			{
				return webAdmin;
			}
		}

		public static SiteBuilderForm SiteBuilder
		{
			get
			{
				return sbf;
			}
		}

		public static InfoForm XedusInfoUI
		{
			get
			{
				return info;
			}
		}

		public static StartForm MainForm
		{
			get{return  sf;}
		}

		public static bool Connected
		{
			get{return connected;}
			set{connected = value;}
		}
		#endregion

       


       

       

        internal static void LoadSettings()
        {
            xsettings = new Settings();
            xstate = new ServerState();
            xstate.LoadSettings(ref xsettings);
        }

        public static void ShutdownXedus()
        {
            if (Start.Connected)
            {
                //AsyncCallback acb = new AsyncCallback(delegate(IAsyncResult res)
                //{
                //    pws.EndDisconnectFromNOW(res);
                //    MessageBox.Show("disconected");
                //    Start.XedusState.XedusSettings.SaveSettings();
                //    Application.Exit();
                //});
                //pws.BeginDisconnectFromNOW(Start.Email,acb,null);
            }
            //if not just save settings and exit
            Start.XedusState.XedusSettings.SaveSettings();
            Start.KillAll();
            Application.Exit();
        }

        
        [STAThread]
        static void Main(string[] args)
        {
            Mutex mx = new Mutex(true, "xedus.LIVE");

            if (mx.WaitOne(1, false))
            {
#if deleting
                DeleteXedusKey();
#else
                if (XedusKey == null)
                {
                    CreateXedusKey();
                    StartXedus();
                }
                else
                {
                    StartXedus();
                }                
            }
            else
                MessageBox.Show("Xedus is already running");
#endif

        }

        private static void StartXedus()
        {
            bool startApplication = true;


            if (startApplication)
            {
                //create all the admin forms
                sf = new StartForm();
                sf.Visible = true;
                Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
                StartServer();
                sf.Hide();
                if (xstate != null)
                {
                    webAdmin = new WebAdmin();
                    sbf = new SiteBuilderForm();
                    info = new InfoForm();
                    MessageBox.Show("Xedus Server has started successfully. Please visit http://www.xedus.net for updates and security fixes", "Xedus Started", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    System.Diagnostics.Process.Start("iexplore", "http://localhost:4274/samples/html/readme.htm");
                    Application.Run();
                }
                else
                {
                    KillAll();
                    MessageBox.Show("Could not start Xedus");
                }
            }
            else
            {
                MessageBox.Show("Could not Connect to Xedus.LIVE");

            }//end if startApplication
        }

        public static void Restart()
        {
            KillAll();
            StartServer();
        }

        public static void StartServer()
        {
            sf.ShowStartupMessage("Loading settings");
            LoadSettings();
            Thread.Sleep(2000);

            sf.ShowStartupMessage("Starting Http Listeners");
            p2 = Process.Start("Xedus.HttpListProc.exe");
            Thread.Sleep(2000);

            sf.ShowStartupMessage("Starting Parallel network drivers");
            Process.Start("Xedus.ParallelNetworkDriver.exe");
            Thread.Sleep(2000);
            running = true;
        }

        public static void KillAll(){
            try
            {
              
                if (!p2.HasExited)
                {
                    p2.Kill();
                }
                foreach (Process proc in Process.GetProcessesByName("Xedus.HttpReqMan"))
                {
                    proc.Kill();
                }
                running = false;
            }
            catch (Exception)
            {
                if (MessageBox.Show("Some auxiliary processes did not shut down currectly.  Do you want Xedus to try to find and shut them down now?","Shut Down Auxiliary Processes?",MessageBoxButtons.YesNo,MessageBoxIcon.Question ) == DialogResult.Yes)
                {
                    StringBuilder err = new StringBuilder("Could not stop auxiliary services.\n" +
                           "Please us Task Manager to stop the following:\n");
                    bool displayErrorMessage = false;
                    try
                    {
                        foreach (Process proc in Process.GetProcessesByName("Xedus.HttpListProc"))
                        {
                            proc.Kill();
                        }
                    }
                    catch (Exception)
                    {
                        displayErrorMessage = true;
                        err.Append("Xedus.HttpListProc\n");
                    }                   

                    try
                    {
                        foreach (Process p in Process.GetProcessesByName("Xedus.HttpReqMan"))
                        {
                            p.Kill();
                        }
                    }
                    catch (Exception)
                    {
                        displayErrorMessage = true;
                        err.Append("Xedus.HttpReqMan");
                    }

                    if(displayErrorMessage)
                        MessageBox.Show(err.ToString());
                }
               
            }
            Thread.Sleep(2000);
        }

		static void SetAddress()
		{
            //string hostName = Dns.GetHostName();
            //IPHostEntry entry = Dns.Resolve(hostName);
            //IPAddress[] addresses = entry.AddressList;
            //ip = addresses[addresses.Length -1].ToString();
		}			

		private static void Log(string format, params string[] args)
		{
            EventLog.WriteEntry("xedus", string.Format(format, args));
        }

        static void Application_ApplicationExit(object sender, EventArgs e)
        {
            KillAll();
        }
    }
}
